(cl:in-package #:coalton-native-tests)

(define-test test-vector-constructor-equivalencies ()
  (let vec = (vector:with-capacity 10))
  (iter:for-each! (fn (x)
                    (vector:push! x vec)
                    Unit)
                  (iter:up-to 10))
  (is (== (vector:make 0 1 2 3 4 5 6 7 8 9)
          vec))
  (is (== (iter:collect! (iter:up-to 10))
          vec)))

(define-test test-vector-initial-element ()
  (== (vector:make "x" "x" "x") (vector:with-initial-element 3 "x")))

(define-test test-vector-basic-operations ()
  (let vec0 = (vector:new))
  (let vec1 = (vector:make 10 11 12 13 14))
  (iter:for-each! (fn (x)
                    (vector:push! x vec0)
                    Unit)
                  (iter:up-to 5))
  (is (== (vector:make 0 1 2 3 4 10 11 12 13 14)
          (vector:append vec0 vec1)))
  (is (== (vector:make 4 3 2 1 0)
          (vector:reverse vec0)))
  (is (== (vector:make 0 1 2 3 4)
          vec0))                        ;ensure vec0 is intact
  (is (== (vector:make 4 3 2 1 0)
          (vector:reverse! vec0)))
  (vector:clear! vec0)
  (is (== (vector:new) vec0))
  (is (== True (vector:empty? vec0)))
  (is (== (Some 2) (vector:find-elem 12 vec1)))
  (is (== None (vector:find-elem 0 vec1)))
  (is (== None (vector:head vec0)))
  (is (== (Some 10) (vector:head vec1)))
  (is (== None (vector:index 1 vec0)))
  (is (== (Some 11) (vector:index 1 vec1)))
  (is (== None (vector:last vec0)))
  (is (== (Some 14) (vector:last vec1)))
  (is (== (Some 14) (vector:pop! vec1)))
  (is (== (Some 13) (vector:last vec1)))
  (vector:push! 9 vec1)
  (is (== (Some 9) (vector:last vec1)))
  (let vec2 = (fold vector:append
                    (vector:singleton 99)
                    (make-list vec1 (vector:make 2 7))))
  (is (== (vector:make 99 10 11 12 13 9 2 7) vec2))
  (vector:sort! vec2)
  (is (== (vector:make 2 7 9 10 11 12 13 99) vec2))
  (vector:sort-by! > vec2)
  (is (== (vector:make 99 13 12 11 10 9 7 2) vec2))
  (vector:set! 3 88 vec2)
  (is (== (vector:make 99 13 12 88 10 9 7 2) vec2))
  (vector:set-capacity! 5 vec2)
  (is (== (vector:make 99 13 12 88 10) vec2))
  (is (== (Some 12) (vector:swap-remove! 2 vec2)))
  (is (== (vector:make 99 13 10 88) vec2))
  (is (== None (vector:swap-remove! 10 vec2)))
  (is (== (vector:make 99 13 10 88) vec2))
  (vector:extend! vec2 (iter:into-iter (make-list 5 6 7 8)))
  (is (== (vector:make 99 13 10 88 5 6 7 8) vec2))

  (let vec3 = (vector:singleton "a"))
  (is (== (Some "a") (vector:swap-remove! 0 vec3)))
  (is (== True (vector:empty? vec3)))
  (is (== None (vector:swap-remove! 0 vec3)))

  (is (== False (vector:singleton? vec2)))
  (is (== False (vector:singleton? (vector:new))))
  (is (== True (vector:singleton? (vector:make 1)))))

(define-test test-vector-resect ()
  (let v = (vector:make 0 1 2 3 4 5 6))
  (vector:resect! v 2 4)
  (is (== v (vector:make 0 1 4 5 6)))

  (let v = (vector:make 0 1 2 3 4 5 6))
  (vector:resect! v 0 400)
  (is (== v (vector:make))))

(define-test test-vector-subseq ()
  (let v = (vector:make 0 1 2 3 4 5 6))
  (is (== (vector:make 2 3) (vector:subseq v 2 4)))
  (is (== v (vector:subseq v 0 1000))))
